{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.1.0\n",
      "sys.version_info(major=3, minor=6, micro=9, releaselevel='final', serial=0)\n",
      "matplotlib 3.1.3\n",
      "numpy 1.18.1\n",
      "pandas 1.0.1\n",
      "sklearn 0.22.1\n",
      "tensorflow 2.1.0\n",
      "tensorflow_core.python.keras.api._v2.keras 2.2.4-tf\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'\\n使用selu作为激活函数，selu自带有归一化数据的功能\\n'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "import tensorflow as tf\n",
    "\n",
    "from tensorflow import keras\n",
    "\n",
    "print(tf.__version__)\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, tf, keras:\n",
    "    print(module.__name__, module.__version__)\n",
    "\n",
    "'''\n",
    "使用selu作为激活函数，selu自带有归一化数据的功能\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(5000, 28, 28) (5000,)\n",
      "(55000, 28, 28) (55000,)\n",
      "(10000, 28, 28) (10000,)\n"
     ]
    }
   ],
   "source": [
    "fashion_mnist = keras.datasets.fashion_mnist\n",
    "(x_train_all, y_train_all), (x_test, y_test) = fashion_mnist.load_data()\n",
    "x_valid, x_train = x_train_all[:5000], x_train_all[5000:]\n",
    "y_valid, y_train = y_train_all[:5000], y_train_all[5000:]\n",
    "\n",
    "print(x_valid.shape, y_valid.shape)\n",
    "print(x_train.shape, y_train.shape)\n",
    "print(x_test.shape, y_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# x = (x - u) / std\n",
    "\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "scaler = StandardScaler()\n",
    "# x_train: [None, 28, 28] -> [None, 1]\n",
    "x_train_scaled = scaler.fit_transform(\n",
    "    x_train.astype(np.float32).reshape(-1, 1)).reshape(-1, 28, 28)\n",
    "x_valid_scaled = scaler.transform(\n",
    "    x_valid.astype(np.float32).reshape(-1, 1)).reshape(-1, 28, 28)\n",
    "x_test_scaled = scaler.transform(\n",
    "    x_test.astype(np.float32).reshape(-1, 1)).reshape(-1, 28, 28)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[4 0 7 9 9]\n"
     ]
    }
   ],
   "source": [
    "print(y_train[0:5])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# tf.keras.models.Sequential()\n",
    "\n",
    "model = keras.models.Sequential()\n",
    "model.add(keras.layers.Flatten(input_shape=[28, 28]))\n",
    "for _ in range(20):\n",
    "    ## 指定激活函数为 selu\n",
    "    model.add(keras.layers.Dense(100, activation=\"selu\"))\n",
    "\n",
    "model.add(keras.layers.Dense(10, activation=\"softmax\"))\n",
    "\n",
    "model.compile(loss=\"sparse_categorical_crossentropy\",\n",
    "              optimizer = \"sgd\",\n",
    "              metrics = [\"accuracy\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "flatten (Flatten)            (None, 784)               0         \n",
      "_________________________________________________________________\n",
      "dense (Dense)                (None, 100)               78500     \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_3 (Dense)              (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_4 (Dense)              (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_5 (Dense)              (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_6 (Dense)              (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_7 (Dense)              (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_8 (Dense)              (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_9 (Dense)              (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_10 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_11 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_12 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_13 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_14 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_15 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_16 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_17 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_18 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_19 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "dense_20 (Dense)             (None, 10)                1010      \n",
      "=================================================================\n",
      "Total params: 271,410\n",
      "Trainable params: 271,410\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 55000 samples, validate on 5000 samples\n",
      "Epoch 1/10\n",
      "55000/55000 [==============================] - 18s 319us/sample - loss: 0.6868 - accuracy: 0.7491 - val_loss: 0.5253 - val_accuracy: 0.8106\n",
      "Epoch 2/10\n",
      "55000/55000 [==============================] - 15s 270us/sample - loss: 0.4868 - accuracy: 0.8243 - val_loss: 0.4591 - val_accuracy: 0.8376\n",
      "Epoch 3/10\n",
      "55000/55000 [==============================] - 16s 285us/sample - loss: 0.4327 - accuracy: 0.8435 - val_loss: 0.4304 - val_accuracy: 0.8454\n",
      "Epoch 4/10\n",
      "55000/55000 [==============================] - 16s 296us/sample - loss: 0.4001 - accuracy: 0.8548 - val_loss: 0.4127 - val_accuracy: 0.8516\n",
      "Epoch 5/10\n",
      "55000/55000 [==============================] - 15s 282us/sample - loss: 0.3757 - accuracy: 0.8637 - val_loss: 0.4034 - val_accuracy: 0.8576\n",
      "Epoch 6/10\n",
      "55000/55000 [==============================] - 18s 324us/sample - loss: 0.3577 - accuracy: 0.8706 - val_loss: 0.3891 - val_accuracy: 0.8608\n",
      "Epoch 7/10\n",
      "55000/55000 [==============================] - 16s 299us/sample - loss: 0.3433 - accuracy: 0.8746 - val_loss: 0.3846 - val_accuracy: 0.8652\n",
      "Epoch 8/10\n",
      "55000/55000 [==============================] - 15s 269us/sample - loss: 0.3315 - accuracy: 0.8795 - val_loss: 0.3635 - val_accuracy: 0.8696\n",
      "Epoch 9/10\n",
      "55000/55000 [==============================] - 14s 260us/sample - loss: 0.3201 - accuracy: 0.8839 - val_loss: 0.3691 - val_accuracy: 0.8696\n",
      "Epoch 10/10\n",
      "55000/55000 [==============================] - 15s 270us/sample - loss: 0.3114 - accuracy: 0.8868 - val_loss: 0.3620 - val_accuracy: 0.8728\n"
     ]
    }
   ],
   "source": [
    "# Tensorboard, earlystopping, ModelCheckpoint\n",
    "logdir = './dnn-selu-callbacks'\n",
    "if not os.path.exists(logdir):\n",
    "    os.mkdir(logdir)\n",
    "output_model_file = os.path.join(logdir,\n",
    "                                 \"fashion_mnist_model.h5\")\n",
    "\n",
    "callbacks = [\n",
    "    keras.callbacks.TensorBoard(logdir),\n",
    "    keras.callbacks.ModelCheckpoint(output_model_file,\n",
    "                                    save_best_only = True),\n",
    "    keras.callbacks.EarlyStopping(patience=5, min_delta=1e-3),\n",
    "]\n",
    "history = model.fit(x_train_scaled, y_train, epochs=10,\n",
    "                    validation_data=(x_valid_scaled, y_valid),\n",
    "                    callbacks = callbacks)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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rFmzOOmkk9i0aRMQvXr6//2//8e0adOYMWMGv/zlL1m+fDkXXnhhfLt/+ctf+MxnPtMXPw4REelj6Tt0e+E22P1u726zbDp8+scHrfbQQw9RWFhIa2srJ5xwAhdccAHXX389K1euZOzYsdTU1ADwox/9iNzcXN59N9rO2trag267srKS1157DafTSUNDA3//+99xuVy88sor3H777TzzzDMsXryYrVu3sm7dOlwuFzU1NRQUFPCVr3yFqqoqiouL+f3vf8+11157ZD8PERFJS+kbzil0//338+c//xmAHTt2sHjxYk499VTGjh0LQGFhIQCvvPIKDz74YPx7BQUFB932JZdcEr+nuL6+nquuuooPPvgAYwzBYDC+3RtvvDF+2Lt9f1/84hf5wx/+wDXXXMPrr7/Oo48+2ks9FhGRdJK+4ZzECPdoKC8v55VXXuH1118nMzOTBQsWcNxxx7Fx48akt2GMic/7/f4O67KysuLz3//+9zn99NP585//zNatWw96D98111zDeeedh8/n45JLLtE5axGRAUrnnDupr6+noKCAzMxMNm7cyBtvvIHf72flypVs2bIFIH5Y+6yzzuK3v/1t/Lvth7VLS0vZsGEDkUgkPgLvaV/Dhw8H4OGHH46Xn3XWWfzmN78hFAp12N+wYcMYNmwYd911F9dcc03vdVpERNKKwrmTs88+m1AoxJQpU7jttts48cQTKS4uZvHixVx00UXMnDmTyy67DIDvfe971NXVMW3aNGbOnMmKFSsA+PGPf8yiRYs46aSTGDp0aI/7+ta3vsV3vvMdZs2aFQ9igOuuu45Ro0YxY8YMZs6cyRNPPBFfd8UVVzBy5EimTJlylH4CIiKSajou2onX6+WFF17odt2nP/3pDsvZ2dn85je/6fLoy4svvpiLL764y/cTR8cA8+fPZ/PmzfHlu+6KPo7c5XLx05/+lJ/+9KddtvHqq69y/fXXJ9UXERHpnxTO/cjs2bPJysrivvvuS3VTRETkKFI49yNr1qxJdRNERKQP6JyziIhImlE4i4iIpBmFs4iISJpROIuIiKQZhbOIiEiaUTgfgcS3T3W2detWpk2b1oetERGRgULhLCIikmbS9j7n/3zrP9lYk/zLJpIxuXAy35777R7X33bbbYwcOZJ/+Zd/AeDOO+/E5XKxYsUKamtrCQaD3HXXXVxwwQWHtF+/389NN93E6tWr40//Ov3003n//fe55pprCAQCRCIRnnnmGYYNG8all15KZWUl4XCY73//+/HHhYqIyOCQtuGcCpdddhn/+q//Gg/nJUuW8NJLL3HrrbeSm5vLvn37OPHEEzn//PM7vHnqYB544AGMMbz77rts3LiRT37yk2zevJlf//rXfPWrX+WKK64gEAgQDod5/vnnGTZsGM899xwQfTmGiIgMLmkbzgca4R4ts2bNYu/evXz88cdUVVVRUFBAWVkZX/va11i5ciUOh4OdO3eyZ88eysrKkt7uq6++yi233ALA5MmTGT16NJs3b2b+/PncfffdVFZWctFFFzFhwgSmT5/ON77xDb797W+zaNEiTjnllKPVXRERSVM659zJJZdcwtNPP81TTz3FZZddxuOPP05VVRVr1qxh3bp1lJaWdnlH8+H6/Oc/z9KlS8nIyOCcc85h+fLlTJw4kbVr1zJ9+nS+973v8cMf/rBX9iUiIv1H2o6cU+Wyyy7j+uuvZ9++ffztb39jyZIllJSU4Ha7WbFiBdu2bTvkbZ5yyik8/vjjLFy4kM2bN7N9+3YmTZpERUUF48aN49Zbb2X79u288847TJ48mcLCQr7whS+Qn5/Pgw8+eBR6KSIi6Uzh3Mmxxx5LY2Mjw4cPZ+jQoVxxxRWcd955TJ8+nTlz5jB58uRD3uZXvvIVbrrpJqZPn47L5eLhhx/G6/WyZMkSHnvsMdxuN2VlZdx+++2sWrWKb37zmzgcDtxuN7/61a+OQi9FRCSdKZy78e6778bni4qKeP3117ut19TURGNjY7frxowZw3vvvQeAz+fj97//fZc6t912G7fddluHsk996lN86lOfOtymi4jIAKBzziIiImlGI+cj9P7773PjjTd2KPN6vbz55pspapGIiPR3CucjdOyxx7Ju3bpUN0NERAYQHdYWERFJMwpnERGRNKNwFhERSTMKZxERkTSjcD4CB3qfs4iIyOFSOA8AoVAo1U0QEZFelLa3Uu3+93+nbUPvvs/ZO2UyZbff3uP63nyfc1NTExdccEG333v00Uf5yU9+gjGGGTNm8Nhjj7Fnzx5uvPFGKioqAPjVr37FsGHDWLRoUfxJYz/5yU9oamrizjvvZMGCBRx33HG8+uqrXH755UycOJG77rqLQCDAkCFDePzxxyktLaWpqYlbbrmF1atXY4zhBz/4AfX19bzzzjv8/Oc/B+Dhhx+moqKCn/3sZ0f08xURkd6RtuGcCr35Pmefz8ef//znLt9bv349d911F6+99hpFRUXU1NQAcOutt3Laaafx5z//mXA4TFNTE7W1tQfcRyAQYPXq1QDU1tbyxhtvYIzhwQcf5J577uG+++7jRz/6EXl5efFHktbW1uJ2u7n77ru59957cbvd/OEPf9ALNkRE0kjahvOBRrhHS2++z9lay+23397le8uXL+eSSy6hqKgIgMLCQgCWL1/Oo48+CoDT6SQvL++g4XzZZZfF5ysrK7nsssvYtWsXgUCAsWPHAvDKK6/w5JNPxusVFBQAsHDhQpYtW8aUKVMIBoNMnz79EH9aIiJytKRtOKdK+/ucd+/e3eV9zm63mzFjxiT1PufD/V4il8tFJBKJL3f+flZWVnz+lltu4etf/zrnn38+5eXl3HnnnQfc9nXXXce///u/M3nyZL7whS8cUrtEROTo0gVhnVx22WU8+eSTPP3001xyySXU19cf1vuce/rewoUL+dOf/kR1dTVA/LD2GWecEX89ZDgcpr6+ntLSUvbu3Ut1dTVtbW0sW7bsgPsbPnw4AI888ki8/KyzzuKBBx6IL7ePxufNm8eOHTt44oknuPjii5P98YiISB9QOHfS3fucV69ezfTp03n00UeTfp9zT9879thj+e53v8tpp53GzJkz+frXvw7AL37xC1asWMH06dOZPXs269evx+12c8cddzB37lzOOuusA+77zjvv5JJLLmH27NnxQ+YA3/ve96itrWXatGnMnDmTFStWxNddeumlnHzyyfFD3SIikh50WLsbvfE+5wN976qrruKqq67qUFZaWsr//d//dal76623cuutt3YpLy8v77B8wQUXdHsVeXZ2doeRdKJXX32Vr33ta92uExGR1NHIeRCqq6tj4sSJZGRkcMYZZ6S6OSIi0olGzkeoP77POT8/n82bN6e6GSIi0gOF8xHS+5xFRKS3pd1hbWttqpsgMfpdiIikRlqFs8/no7q6WqGQBqy1VFdX4/P5Ut0UEZFBJ60Oa48YMYLKykqqqqpS3ZSk+f3+fh9gPfXB5/MxYsSIFLRIRGRwSyqcjTFnA78AnMCD1tofd1rvBR4FZgPVwGXW2q2H2hi32x1/7GR/UV5ezqxZs1LdjCMyEPogIjKQHPSwtjHG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\n",
      "text/plain": [
       "<Figure size 576x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def plot_learning_curves(history):\n",
    "    pd.DataFrame(history.history).plot(figsize=(8, 5))\n",
    "    plt.grid(True)\n",
    "    plt.gca().set_ylim(0, 1)\n",
    "    plt.show()\n",
    "\n",
    "plot_learning_curves(history)\n",
    "\n",
    "# 1. 参数众多，训练不充分\n",
    "# 2. 梯度消失 -> 链式法则 -> 复合函数f(g(x))\n",
    "#    selu缓解梯度消失"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10000/10000 [==============================] - 1s 145us/sample - loss: 0.3994 - accuracy: 0.8570\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[0.39935172288417814, 0.857]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.evaluate(x_test_scaled, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
